package com.dyava.commons.lock.local;

import com.dyava.commons.lock.KeyLock;
import com.dyava.commons.lock.KeyLockException;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by jjliu on 2020/4/15.
 */
@Deprecated
public class LocalKeyLock3  {
    ConcurrentHashMap<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();


    ReentrantLock obtainLock(String key){
        ReentrantLock lock = lockMap.get(key);
        while(lock==null){
            lock = new ReentrantLock();
            Object _lock = lockMap.putIfAbsent(key,lock);
            if(_lock !=null ){ //被别人放入
                lock = lockMap.get(key);
            }
        }
        return lock;
    }

    public boolean tryLock(String key) {
        ReentrantLock lock = obtainLock(key);
        return lock.tryLock();
    }

    public void lock(String key, int maxWaitTime) {
        while (true){
            ReentrantLock lock = obtainLock(key);
            try {
                lock.tryLock(maxWaitTime, TimeUnit.MILLISECONDS);
                break;
            } catch (InterruptedException e) {
                continue;
            }
        }
    }

    public void close(String key) {
        ReentrantLock lock = lockMap.get(key);
        if(lock!=null){
            if(!lock.hasQueuedThreads()) { //没人等
                lockMap.remove(lock);// 从lockMap中 剔除锁
                if(lock.hasQueuedThreads()){ //此刻居然有沙雕在等
                    try {
                        lock.lockInterruptibly();//沙雕去死吧
                    } catch (InterruptedException e) {}
                }
            }
            lock.unlock();
        }else{
            throw new KeyLockException("锁定代码异常，锁丢失");
        }
    }
}
